package com.fishsticks.view;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import com.fishsticks.R;
import com.fishsticks.model.Category;
import com.fishsticks.model.DropDownListAdapter;
import com.fishsticks.model.DatabaseManager;
import com.fishsticks.model.NewCategoryDialog;
import com.fishsticks.model.ToDoItem;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

public class AddNewToDoActivity extends Activity 
{
	private EditText title, description;
	private TextView latitude, longitude;
	private Spinner categorySpinner;
	private Button dateButton, mapButton;
	private static final int DATE_PICKER_ID = 111; 
	private int year, month, day;
	private Category[] categories;
	private DatabaseManager db;
	private String currentUser;
	private Bundle extras;
	private DropDownListAdapter categoriesAdapter;
	private Date selectedDate, currentDate;
	private AlertDialog rtn;
	private AlertDialog.Builder dateDialog, dialog;
	private boolean refreshList, returningFromToDoList, returningFromMap;
	private NewCategoryDialog newCategoryDialog;
	private ArrayList<Category> categoryList;
	private Geocoder geocoder;

	/**
     * Called when the activity is first created.
     * Initializes new to-do list item page 
     * and action bar buttons on top
     */
    @SuppressWarnings("deprecation")
	@Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
        this.setContentView(R.layout.add_new_to_do_page);
        
        title = (EditText) findViewById(R.id.titleFieldAddPage);
        description = (EditText) findViewById(R.id.descriptionFieldAddPage);
        latitude = (TextView) findViewById(R.id.latitudeTextAddPage);
        longitude = (TextView) findViewById(R.id.longitudeTextAddPage);
        dateButton = (Button) findViewById(R.id.dateButtonAddPage);
        categorySpinner = (Spinner) findViewById(R.id.categorySpinner);
        newCategoryDialog = new NewCategoryDialog(this, AlertDialog.THEME_HOLO_LIGHT);
        mapButton = (Button) findViewById(R.id.mapButtonAddPage);
        
        db = new DatabaseManager(this);
        
        // Gets recently created username if coming 
        // from the registration page
        extras = getIntent().getExtras();
        if(extras != null) 
        {
        	currentUser = extras.getString("username");
        	
        	//resets the location strings
        	if(extras.getBoolean("locationChanged")) {
        		latitude.setText(new Double(extras.getDouble("newLatitude")).toString());
        		longitude.setText(new Double(extras.getDouble("newLongitude")).toString());
        	}
        	
        	else if(!extras.getBoolean("locationChanged")) {
        		latitude.setText(new Double(extras.getDouble("oldLatitude")).toString());
        		longitude.setText(new Double(extras.getDouble("oldLongitude")).toString());
        	}
        	
        	//sets the location to a default addresss
        	else {
        		//set latitude/longitude to ATL, GA by default
                geocoder = new Geocoder(this, Locale.getDefault());
                try {
        			List<Address> addresses = geocoder.getFromLocationName("120 North Avenue NW, Atlanta, Georgia", 2);
        			
        			if(addresses.size() > 0) {
        				latitude.setText(new Double(addresses.get(0).getLatitude()).toString());
        				longitude.setText(new Double(addresses.get(0).getLongitude()).toString());
        			}
        			else {
        				latitude.setText("0.0000");
        				longitude.setText("0.0000");
        			}
        		} 
                catch (IOException e) {
        			e.printStackTrace();
        		}
        	}
        }
        
        loadCategories();
        
        dateButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				// Opens dialog box with date picker
				showDialog(DATE_PICKER_ID);
			}
        });
        
		final Intent mapsIntent = new Intent(this, MapsActivity.class);        
        mapButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {
				// Opens dialog box with date picker
				mapsIntent.putExtra("showSingleToDo", true);
				mapsIntent.putExtra("latitudeNum", latitude.getText().toString());
				mapsIntent.putExtra("longitudeNum", longitude.getText().toString());
				returningFromToDoList = false;
        		returningFromMap = true;
            	startActivityForResult(mapsIntent, 33);
			}
        });
        
        categorySpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
        	@Override
        	public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
        		if(parent.getItemAtPosition(pos).toString().equals("Add new category")) {
        			
        			newCategoryDialog.setPositiveButton("Add", new Dialog.OnClickListener() {
        		        public void onClick(DialogInterface dialog, int which) {
        			           newCategoryDialog.addNewCategory();
        			           loadCategories();
        			           categoriesAdapter.notifyDataSetChanged();
        			    }
        			});
        			
        			newCategoryDialog.show();
        			
        		}
        	}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {}
        });
        
        
        
        if(savedInstanceState != null) {
	        if(!savedInstanceState.getBoolean("returningFromToDoList") && 
	    		savedInstanceState.getBoolean("returningFromMap")) {
	    		title.setText(savedInstanceState.getString("title"));
	    		description.setText(savedInstanceState.getString("description"));
	    		latitude.setText(savedInstanceState.getString("latitude"));
	    		longitude.setText(savedInstanceState.getString("longitude"));
	    		dateButton.setText(savedInstanceState.getString("date"));
	    		categorySpinner.setSelection(savedInstanceState.getInt("category"));
	    		selectedDate =  
	    				new Date(new Integer(dateButton.getText().toString().substring(6, dateButton.getText().toString().length())).intValue(),
	    						 new Integer(dateButton.getText().toString().substring(0, 2)).intValue() - 1,
	    						 new Integer(dateButton.getText().toString().substring(3, 5)).intValue());
	        }
        }
        
        
        setCurrentDate();
        db.close();
    }
    
    
    
    
    /**
     * System method called when the activity is about to be terminated;
     *  saves inputted data so it will be restored later
     *  
     *  @param savedInstanceState The Bundle of saved data 
     */
    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
    	if(savedInstanceState != null) {
	    	savedInstanceState.putBoolean("returningFromMap", returningFromMap);
	    	savedInstanceState.putBoolean("returningFromToDoList", returningFromToDoList);
	    	savedInstanceState.putString("title", title.getText().toString());
	    	savedInstanceState.putString("description", description.getText().toString());
	    	savedInstanceState.putString("latitude", latitude.getText().toString());
	    	savedInstanceState.putString("longitude", longitude.getText().toString());
	    	savedInstanceState.putString("date", dateButton.getText().toString());
	    	savedInstanceState.putInt("category", categorySpinner.getSelectedItemPosition());
	    	super.onSaveInstanceState(savedInstanceState);
    	}
    }
    
    
    
    
    
    /**
     * System method called when the activity is about to be resumed;
     *  resumes saved data so it will be restored properly
     *  
     *  @param savedInstanceState The Bundle of saved data 
     */
    @SuppressWarnings("deprecation")
	@Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
    	if(savedInstanceState != null) {
	    	if(!savedInstanceState.getBoolean("returningFromToDoList") && 
	    		savedInstanceState.getBoolean("returningFromMap")) {
	    		title.setText(savedInstanceState.getString("title"));
	    		description.setText(savedInstanceState.getString("description"));
	    		latitude.setText(savedInstanceState.getString("latitude"));
	    		longitude.setText(savedInstanceState.getString("longitude"));
	    		dateButton.setText(savedInstanceState.getString("date"));
	    		categorySpinner.setSelection(savedInstanceState.getInt("category"));
	    		selectedDate =  
	    				new Date(new Integer(dateButton.getText().toString().substring(6, dateButton.getText().toString().length())).intValue(),
	    						 new Integer(dateButton.getText().toString().substring(0, 2)).intValue() - 1,
	    						 new Integer(dateButton.getText().toString().substring(3, 5)).intValue());
	    	}
    	}
    }
    
    
    
    
    
    /**
     * Called when the activity is "resumed" from another activity.
     * i.e. it was in the background but not destroyed.
     */
    @Override
    public void onResume() {
    	extras = getIntent().getExtras();
        if(extras != null) 
        {
        	currentUser = extras.getString("username");
        	
        	//resets the location strings
        	if(extras.getBoolean("singleToDoChanged")) {
        		latitude.setText(new Integer(extras.getInt("newLatitude")).toString());
        		longitude.setText(new Integer(extras.getInt("newLongitude")).toString());
        	}
        }
        super.onResume();
    }
    
    
    
    
    /**
     * Helper method to load the user's categories 
     * 		into the category drop-down menu
     */
    public void loadCategories() {
    	if(categoryList != null)
    		categoryList.clear();
    	categoryList = db.getCategories(db.getLoggedInUser());
        categoryList.add(0, new Category("Select a category"));
        categoryList.add(categoryList.size(), new Category("Add new category"));
        categorySpinner.setSelection(categorySpinner.getCount()-1);
        categoriesAdapter = new DropDownListAdapter(this, R.layout.category_drop_down_item_row, categoryList);
        categorySpinner.setAdapter(categoriesAdapter);
    }
    
    
    
    
    /**
     * Helper method to convert a category arraylist to an array
     * 
     * @param categoryList An arraylist of categories
     * @return An array of categories
     */
    public Category[] convertToArray(ArrayList<Category> categoryList)
    {
    	Category[] categoryArray = new Category[categoryList.size()];
    	
    	for(int i=0; i<categoryArray.length; i++)
    	{
    		categoryArray[i] = categoryList.get(i);
    	}
    	
    	return categoryArray;
    }
    
    
    
    
    /**
     * Sets the current date on the date button
     */
 	public void setCurrentDate() 
 	{  
 		final Calendar c = Calendar.getInstance();
 		year = c.get(Calendar.YEAR);
 		month = c.get(Calendar.MONTH);
 		day = c.get(Calendar.DAY_OF_MONTH);
  
 		// set current date into textview
 		dateButton.setText(new StringBuilder()
 							.append(month + 1).append("/")
 							.append(day).append("/")
 							.append(year));  
 		
 		currentDate = new Date(year, month, day);
 		selectedDate = new Date(year, month, day);
 	}
    
    
    
 	
 	
 	
 	/**
 	 * Overriding the system method of showing a dialog box that
 	 * 		populates the date picker with the current date
 	 */
    @Override
	protected Dialog onCreateDialog(int id) 
    {
		switch (id) 
		{
			case DATE_PICKER_ID:
				// set date picker as current date
				dateDialog = new AlertDialog.Builder(this, R.style.white_orange_dialog);
				dateDialog.setTitle("Select Date");
				
				Context mContext = getBaseContext();
            	LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE);
            	View dateDialogView = inflater.inflate(R.layout.date_dialog, (ViewGroup)findViewById(R.id.date_dialog_root));
            	
            	//Gets the check box in the dialog
            	final DatePicker datePicker = (DatePicker) dateDialogView.findViewById(R.id.datePickerDateDialog);
            	datePicker.updateDate(currentDate.getYear(), currentDate.getMonth(), currentDate.getDate());
            	
            	dateDialog.setPositiveButton("Okay", new DialogInterface.OnClickListener() {
        			@Override
        			public void onClick(DialogInterface dialog, int which) {
        				year = datePicker.getYear();
        	    		month = datePicker.getMonth();
        	    		day = datePicker.getDayOfMonth();
        	    		
        	    		// set selected date into textview
        	    		dateButton.setText(new StringBuilder()
        	    							.append(month + 1).append("/")
        	    							.append(day).append("/")
        	    							.append(year));
        	    		
        	    		selectedDate = new Date(year, month, day);
        			}
        		});
            	
            	dateDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        			@Override
        			public void onClick(DialogInterface dialog, int which) {
        				dialog.dismiss();
        			}
        		});
            	
            	dateDialog.setView(dateDialogView);
            	
				return dateDialog.create();
		}
		return null;
	}
    
    
    
    
    
    /**
     * Custom DatePicker dialog box with a custom listener 
     * 		to show a date picker in a dialog box
     */
    private DatePickerDialog.OnDateSetListener datePickerListener 
    		= new DatePickerDialog.OnDateSetListener() {

    	// when dialog box is closed, below method will be called.
    	public void onDateSet(DatePicker view, int selectedYear, int selectedMonth, int selectedDay) 
    	{
    		year = selectedYear;
    		month = selectedMonth;
    		day = selectedDay;
    		
    		// set selected date into textview
    		dateButton.setText(new StringBuilder()
    							.append(month + 1).append("/")
    							.append(day).append("/")
    							.append(year));
    		
    		selectedDate = new Date(selectedYear, selectedMonth, selectedDay);
    	}
    };
    
    
    
    
    
    
    /**
     * Creates the menu options in the action bar at the top.
     * 
     * @param menu The android system Menu item to use
     * @return A boolean representing a successful menu creation
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
    {
        getMenuInflater().inflate(R.menu.new_to_do_menu, menu);
        return true;
    }
    
    
    
    
    
    
    
    /**
     * Listeners for the top bar menu items
     * 
     * @param item The menu item that was clicked (buttons)
     * @return boolean for a successful click
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) 
    {
    	Intent i = null;
    	
        switch (item.getItemId()) 
        {       
            //Goes to to-do list page when check button clicked
            case R.id.accept_new_to_do:
            	//add the item if its valid
            	if(addToDoItemIfValid()) {
	            	//i = new Intent(this, ToDoListActivity.class);
	            	//i.putExtra("refreshList", true);
	            	//i.putExtra("newUsername", currentUser);
	            	//i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
	            	//startActivity(i);
            		refreshList = true;
            		returningFromToDoList = true;
            		returningFromMap = false;
            		finish();
            	}
	            return true;
            	
            //Goes to to-do list page when check button clicked
            case R.id.cancel_new_to_do:
            	//i = new Intent(this, ToDoListActivity.class);
            	//i.putExtra("refreshList", false);
            	//i.putExtra("oldUsername", currentUser);
            	//i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            	//startActivity(i);
            	refreshList = false;
            	returningFromToDoList = true;
        		returningFromMap = false;
            	finish();
            	return true;
            	
            case android.R.id.home:
            	refreshList = false;
            	finish();
            	return true;
                
            default:
                return super.onOptionsItemSelected(item);
        }
    }
    
    
    /**
     * System method called when the activity is terminated
     */
    @Override
    public void finish() {
    	Intent i = new Intent();
    	i.putExtra("refreshList", refreshList);
    	i.putExtra("username", currentUser);
    	i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
    	setResult(R.string.add_to_do_successful_code, i);
    	super.finish();
    }
    
    
    
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
    	if(requestCode == 33) {
    		Bundle intentExtras = data.getExtras();
            if(intentExtras != null) 
            {
            	currentUser = intentExtras.getString("username");
            	
            	
            	if(intentExtras.getBoolean("locationChanged")) {
            		latitude.setText(new Double(intentExtras.getDouble("newLatitude")).toString());
            		longitude.setText(new Double(intentExtras.getDouble("newLongitude")).toString());
            	}
            	
            	else if(!intentExtras.getBoolean("locationChanged")) {
            		latitude.setText(new Double(intentExtras.getDouble("oldLatitude")).toString());
            		longitude.setText(new Double(intentExtras.getDouble("oldLongitude")).toString());
            	}
            }	
    	}
    }
    
    
    
    /**
     * Adds a new to do item if the fields are valid
     * 
     * @return A boolean representing the success 
     *          or failure of the to-do addition
     */
    public boolean addToDoItemIfValid() {
    	
    	int errorCode = db.addToDoItem(title.getText().toString(), description.getText().toString(), selectedDate, currentUser, 
    					(Category)categorySpinner.getSelectedItem(), latitude.getText().toString(), longitude.getText().toString());
    	
    	dialog = new AlertDialog.Builder(this);
    	
    	//if successful
    	if(errorCode == -1) {
    		db.close();
    		Intent i = new Intent(this, ToDoListActivity.class);
        	i.putExtra("refreshList", true);
        	i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
        	startActivity(i);
        	finish();
        	return true;
    	}
    	
    	else if(errorCode == R.string.add_to_do_error_code_blank_fields) {
    		dialog = new AlertDialog.Builder(this, AlertDialog.THEME_HOLO_LIGHT);
			dialog.setTitle("Error");
			dialog.setMessage(getResources().getString(R.string.add_to_do_error_message_blank_fields));
			dialog.setPositiveButton("Okay", new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					rtn.dismiss();
				}
			});
			rtn = dialog.show();
    	}
    	
    	else if(errorCode == R.string.add_to_do_error_code_date_too_early) {
    		dialog = new AlertDialog.Builder(this, AlertDialog.THEME_HOLO_LIGHT);
			dialog.setTitle("Error");
			dialog.setMessage(getResources().getString(R.string.add_to_do_error_message_date_too_early));
			dialog.setPositiveButton("Okay", new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					rtn.dismiss();
				}
			});
			rtn = dialog.show();
    	}
    	
    	else if(errorCode == R.string.add_to_do_error_code_no_category) {
    		dialog = new AlertDialog.Builder(this, AlertDialog.THEME_HOLO_LIGHT);
			dialog.setTitle("Error");
			dialog.setMessage(getResources().getString(R.string.add_to_do_error_message_no_category));
			dialog.setPositiveButton("Okay", new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					rtn.dismiss();
				}
			});
			rtn = dialog.show();
    	}
    	
    	else if(errorCode == R.string.add_to_do_error_code_no_latitude) {
    		dialog = new AlertDialog.Builder(this, AlertDialog.THEME_HOLO_LIGHT);
			dialog.setTitle("Error");
			dialog.setMessage(getResources().getString(R.string.add_to_do_error_message_no_latitude));
			dialog.setPositiveButton("Okay", new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					rtn.dismiss();
				}
			});
			rtn = dialog.show();
    	}
    	
    	else if(errorCode == R.string.add_to_do_error_code_no_longitude) {
    		dialog = new AlertDialog.Builder(this, AlertDialog.THEME_HOLO_LIGHT);
			dialog.setTitle("Error");
			dialog.setMessage(getResources().getString(R.string.add_to_do_error_message_no_longitude));
			dialog.setPositiveButton("Okay", new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					rtn.dismiss();
				}
			});
			rtn = dialog.show();
    	}
    	
    	return false;
    }
	
}
